package service.impl;

import global.Constants;
import global.security.SessionUtils;

import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import service.FeedService;
import util.FileUtils;
import util.StringUtils;
import dao.FeedDAO;
import domain.Feed;

/**
 * 订阅Service实现类.
 * <p>
 * 创建日期：2010-07-01<br>
 * 创建人：Xiyt<br>
 * 修改日期：<br>
 * 修改人：<br>
 * 修改内容：<br>
 * 
 * @author Xiyt
 * @version 1.0
 */
public class FeedServiceImpl implements FeedService {

	/**
	 * 订阅Dao
	 * */
	private FeedDAO feedDao = null;

	/**
	 * 设定订阅Dao
	 * */
	public void setFeedDao(FeedDAO feedDao) {
		this.feedDao = feedDao;
	}

	/**
	 * 查询订阅数量
	 * @param paramNote 订阅
	 * @return int 订阅数量
	 */
	public int countByCriteria(Feed paramFeed) {
		paramFeed = getConditions(paramFeed);
		int count = feedDao.countByCriteria(paramFeed);
		return count;
	}

	/**
	 * 获得订阅
	 * @param feedId 订阅ID
	 * @return Feed 订阅
	 */
	public Feed selectByPrimaryKey(Integer feedId){
		return feedDao.selectByPrimaryKey(feedId);
	}

	/**
	 * 查询订阅列表
	 * @param paramNote 订阅
	 * @return List 订阅列表
	 */
	public List<Feed> selectByCriteria(Feed paramFeed) {
		// 查询订阅列表
		paramFeed = getConditions(paramFeed);
		List<Feed> feedList = feedDao.selectByCriteria(paramFeed);
		if (feedList != null && feedList.size() != 0) {
			return feedList;
		} else {
			return null;
		}
	}
	
	/**
	 * 查询订阅树
	 * @return JSONArray 分类树
	 */
	public JSONArray selectFeedForTree(String parentId){
		JSONArray res = new JSONArray();
		Feed paramFeed = new Feed();
		if(StringUtils.isNotEmpty(parentId)){
			paramFeed.setParentId(Integer.parseInt(parentId));
		}
		// 取得订阅分类列表
		List<Feed> feedList = new ArrayList<Feed>();
		feedList = this.selectByCriteria(paramFeed);
		res = getFeedTreeFromList(feedList, parentId);
		return res;
	}

	/**
	 * 添加订阅
	 * @param feed 订阅
	 */
	public void insert(Feed feed) {
		// 删除区分：未删除
		feed.setDelflag(Constants.DEL_FLAG_1);
		// 系统时间
		Timestamp sysdate = new Timestamp(System.currentTimeMillis());
		feed.setCreateUser(SessionUtils.getCurrentUserId());
		feed.setCreateTime(sysdate);
		feed.setUpdateUser(SessionUtils.getCurrentUserId());
		feed.setUpdateTime(sysdate);
		feedDao.insert(feed);
	}

	/**
	 * 修改订阅
	 * @param feed 订阅
	 */
	public void update(Feed feed) {
		// 系统时间
		Timestamp sysdate = new Timestamp(System.currentTimeMillis());
		feed.setUpdateUser(SessionUtils.getCurrentUserId());
		feed.setUpdateTime(sysdate);
		feedDao.updateByPrimaryKey(feed);
	}

	/**
	 * 删除订阅
	 * @param feedId 订阅ID
	 * @param feedFilePath 订阅文件路径
	 * @throws Exception 
	 */
	public void delete(int feedId, String feedFilePath) throws Exception {
		// 取得订阅列表
		List<Feed> feedList = new ArrayList<Feed>();
		// 递归查询订阅
		Feed parentFeed = new Feed();
		if(0 == feedId){// 根目录
			parentFeed.setFeedId(feedId);
		}else{
			parentFeed = this.selectByPrimaryKey(feedId);
		}
		getFeedList(parentFeed, feedList);
		
		for (Feed feed : feedList) {
			// 删除订阅
			feedDao.deleteByPrimaryKey(feed.getFeedId());
			// 删除订阅文件
			FileUtils.delete(feedFilePath+"/"+feed.getFeedId()+".xml");
		}
		// 删除跟订阅
		feedDao.deleteByPrimaryKey(feedId);
	}

	/**
	 * 更新订阅信息
	 * @param feedId 订阅ID
	 * @param feedFilePath 订阅文件路径
	 */
	public void refreshFeed(int feedId, String feedFilePath) throws Exception{
		// 取得订阅列表
		List<Feed> feedList = new ArrayList<Feed>();
		// 递归查询订阅
		Feed parentFeed = new Feed();
		if(0 == feedId){// 根目录
			parentFeed.setFeedId(feedId);
		}else{
			parentFeed = this.selectByPrimaryKey(feedId);
		}
		getFeedList(parentFeed, feedList);
		for (Feed feed : feedList) {
			if(Constants.ISLEAF_TRUE_CODE.equals(feed.getIsleaf())){
				FileUtils.saveFileByUrl(feed.getFeedUrl(),feedFilePath+"/"+feed.getFeedId()+".xml");
			}
		}
	}
	
	/**
	 * 返回订阅树
	 * 
	 * @param feedList
	 * @return
	 */
	private JSONArray getFeedTreeFromList(List<Feed> feedList, String parentId) {
		JSONArray results = new JSONArray();
		
		if("-1".equals(parentId)){
			JSONObject feedFavorite = new JSONObject();
			feedFavorite.put("id", "feedFavorite");
			feedFavorite.put("text", "订阅收藏夹");
			feedFavorite.put("leaf", true);
			results.add(feedFavorite);
			JSONObject feed = new JSONObject();
			feed.put("id", "0");
			feed.put("text", "我的订阅");
			feed.put("leaf", false);
			results.add(feed);
		}else{
			if (null != feedList) {
				for (int i = 0; i < feedList.size(); i++) {
					Feed tempFeed = feedList.get(i);
					JSONObject feedNode = new JSONObject();
					feedNode.put("id", tempFeed.getFeedId());
					feedNode.put("text", tempFeed.getFeedName());
					feedNode.put("leaf", Constants.ISLEAF_MAP.get(tempFeed.getIsleaf()));
					feedNode.put("attributes", "{feedUrl:'"+tempFeed.getFeedUrl()+"',feedCount:'"+tempFeed.getFeedCount()+"'}");
					results.add(feedNode);
				}
			}
		}
		return results;
	}
	

	/**
	 * 导入订阅列表
	 * @param feedId 订阅ID
	 * @param feedFilePath 订阅文件路径
	 * @throws Exception 
	 */
	public void importOpml(String feedId, InputStream in) throws Exception{
		Document doc = Jsoup.parse(in, "UTF-8", "");
		// 获得所有图片
		Elements outlines = doc.getElementsByTag("outline");
		String title, xmlUrl;
		for (Element outline : outlines) {
			if(outline.hasAttr("title") && outline.hasAttr("xmlUrl")){
				title =  outline.attr("title");
				xmlUrl = outline.attr("xmlUrl");
				if(StringUtils.isNotEmpty(title) && StringUtils.isNotEmpty(xmlUrl)){
					Feed feed = new Feed();
					feed.setParentId(Integer.parseInt(feedId));
					feed.setFeedName(title);
					feed.setFeedUrl(xmlUrl);
					feed.setIsleaf(Constants.ISLEAF_TRUE_CODE);
					feed.setFeedCount(50);
					feed.setStatus(Constants.STATUS_1);
					
					// 插入订阅
					this.insert(feed);
				}
			}
		}
	}
	
	
	/**
	 * 导出订阅列表
	 * @param feedId 订阅目录ID
	 * @param templateFilePath 模板文件路径
	 * @throws Exception 
	 */
	public void exportOpml(String feedId, String templateFilePath) throws Exception{
		List<Feed> feedList = new ArrayList<Feed>();
		// 查询订阅目录下的所有订阅，包括子目录
		Feed paramFeed = new Feed();
		paramFeed.setFeedId(Integer.parseInt(feedId));
		getFeedList(paramFeed, feedList);
		
		// 生成订阅列表OPML文件
		String outlines = "";
		for (Feed feed : feedList) {
			if(Constants.ISLEAF_TRUE_CODE.equals(feed.getIsleaf())){
				outlines += "<outline title='"+feed.getFeedName()+"' text='"+feed.getFeedName()+"' xmlUrl='"+feed.getFeedUrl()+"' />" + "\r\n";
			}
		}
		FileUtils.createFileWithEncoder(templateFilePath, Constants.OPML_TEMPLET_START+outlines+Constants.OPML_TEMPLET_END, "UTF-8");
	}
	
	/**
	 * 递归查询订阅
	 * 
	 * @param parentFeed 订阅
	 * @param feedList 订阅
	 * @return
	 */
	private void getFeedList(Feed parentFeed, List<Feed> feedList){
		// 添加本订阅
		feedList.add(parentFeed);
		// 递归查询子订阅
		Feed paramFeed = new Feed();
		paramFeed.setParentId(parentFeed.getFeedId());
		List<Feed> newFeedList = this.selectByCriteria(paramFeed);
		if(null != newFeedList){
			for(int i=0;i<newFeedList.size();i++){
				getFeedList(newFeedList.get(i), feedList);
			}
		}
	}
	
	/**
	 * 设置公共参数
	 * @param paramFeed 参数对象
	 */
	private Feed getConditions(Feed paramFeed){
		paramFeed.setCreateUser(SessionUtils.getCurrentUserId());// 当前用户
		return paramFeed;
	}
}
